﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Windows.Forms;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Smo.RegisteredServers;
using Microsoft.Win32;

namespace ADEVSO.Data.SqlClient
{
    static public class SqlServerManagement
    {
        /// <summary>
        /// Get Network Servers
        /// </summary>
        /// <param name="worker"></param>
        static public List<String> GetServers(System.ComponentModel.BackgroundWorker worker)
        {
            List<String> servers = new List<String>();
            try
            {
                // Load SMO Enum Servers
                ReportProgress(worker, 5);
                System.Data.DataTable dt = SmoApplication.EnumAvailableSqlServers(false);
                ReportProgress(worker, 20);
                // Load Registered Servers
                RegisteredServer[] rsvrs = SqlServerRegistrations.EnumRegisteredServers();
                ReportProgress(worker, 40);
                // Load Registry for local
                RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server");
                String[] instances = rk.GetValue("InstalledInstances") as String[];
                ReportProgress(worker, 60);

                // Set total servers
                int totalServers = dt.Rows.Count;
                if (rsvrs != null) totalServers += rsvrs.Length;
                if (instances != null) totalServers += instances.Length;
                int currentServer = 0;

                // Populate Enum Servers
                if (dt.Rows.Count > 0)
                {
                    // Load server names into combo box
                    foreach (DataRow dr in dt.Rows)
                        AddServer(ref servers, dr["Name"].ToString(), worker, ref currentServer, totalServers);
                }

                // Populate Registry for local
                if (instances != null && instances.Length > 0)
                {
                    foreach (String element in instances)
                    {
                        String name = "";
                        //only add if it doesn't exist
                        if (element == "MSSQLSERVER")
                            name = System.Environment.MachineName;
                        else
                            name = System.Environment.MachineName + @"\" + element;
                        AddServer(ref servers, name, worker, ref currentServer, totalServers);
                    }
                }

                // Populate Registered Servers
                foreach (RegisteredServer rs in rsvrs)
                {
                    String name = rs.ServerInstance.Replace(".", Environment.MachineName)
                                        .Replace("(local)", Environment.MachineName)
                                        .Replace("localhost", Environment.MachineName);
                    AddServer(ref servers, name, worker, ref currentServer, totalServers);
                }
            }
            catch
            {
            }
            return servers;
        }

        static private void AddServer(ref List<String> servers, String server, System.ComponentModel.BackgroundWorker worker, ref int current, int total)
        {
            // Only add if it doesn't exist
            if (! servers.Contains(server))
            {
                servers.Add(server);
                current++;
                ReportProgress(worker, (current * 40 / total) + 60);
            }
        }

        static private void ReportProgress(System.ComponentModel.BackgroundWorker worker, int percentage)
        {
            worker.ReportProgress(percentage);
            int timer = 0;
            while (timer++ < 500)
                Application.DoEvents();
        }
    }
}
